/*
 * Reaction.h
 *
 *  Created on: 23 May 2011
 *      Author: allan
 */

#ifndef REACTION_H_
#define REACTION_H_

// C++ includes
#include <string>
#include <vector>
using namespace std;

class System;

class Reaction
{
public:
	Reaction();
	
	virtual ~Reaction();
	
	void SetNameOfReactant(string nameOfReactant);
	
	void SetNameOfProducts(const vector<string>& nameOfProducts);
	
	void SetIndexOfReactant(unsigned indexOfReactant);
	
	void SetIndexOfProducts(const vector<unsigned>& indexOfProducts);
	
	void SetStoichiometryOfProducts(const vector<double>& stoichiometryOfProducts);
	
	void SetEquilibriumConstant(const vector<double>& logK, const vector<double>& temperatures);
	
	const unsigned GetNumOfProducts() const;
	
	const string GetNameOfReactant() const;
	
	const string GetNameOfProduct(unsigned iProduct) const;
	
	const unsigned GetIndexOfReactant() const;
	
	const unsigned GetIndexOfProduct(unsigned iProduct) const;
	
	const double GetStoichiometryOfProduct(unsigned iProduct) const;
	
	const double GetStoichiometryOfSpecies(unsigned iSpecies) const;
	
	const double EquilibriumConstant(double T, double P) const;
	
private:
	/// The name of the species in the system that is the reactant of this reaction.
	string nameOfReactant;
	
	/// The names of the species in the system that are the products of this reaction.
	vector<string> nameOfProducts;
	
	/// The index of species in the system that is the reactant of this reaction.
	unsigned indexOfReactant;
	
	/// The indexes of the species in the system that are the products of this reaction.
	vector<unsigned> indexOfProducts;
	
	/// The stoichiometry of each product in this reaction.
	vector<double> stoichiometryOfProducts;
	
	/// The logarithm (base 10) of the equilibrium constants in molar fraction scale.
	vector<double> logK;
	
	/// The temperature points where the equilibrium constansts are interpolated.
	vector<double> temperatures;
};

class EquilibriumReaction : public Reaction
{
public:
	EquilibriumReaction();
	
	virtual ~EquilibriumReaction();
};

class KineticReaction : public Reaction
{
public:
	KineticReaction();
	
	virtual ~KineticReaction() = 0;
	
	virtual const double ReactionRate(double T, double P, const System& system) const = 0;
};

struct MineralReactionMechanism
{
	/// The kinetic rate constant of the mineral reaction at 298.15 K
	double k;
	
	/// The Arrhenius activation energy.
	double Ea;
	
	/// The indexes of the species that participate in the mineral reaction, e.g., H[+], OH[-], Fe[3+], Al[3+], etc.
	vector<unsigned> iSpecies;
	
	/// The exponent values of the activities of the species that participate in the mineral reaction.
	vector<double> nSpecies;
};

class MineralReaction : public KineticReaction
{
public:
	MineralReaction();
	
	virtual ~MineralReaction();

	void AddMechanisms(const MineralReactionMechanism& mechanism);
	
	void SetSpecificSurfaceArea(double specificSurfaceArea);

	const double ReactionRate(double T, double P, const System& system) const;

private:
	/// The mechanisms that are considered in the calculation of the mineral rate of precipitation/dissolution.
	vector<MineralReactionMechanism> mechanisms;

	/// The specific surface area of the mineral used in the calculation of its rate of precipitation/dissolution.
	double specificSurfaceArea;
};

#endif /* REACTION_H_ */
